home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / ZANSI12.ZIP / ZANSI_F.ASM < prev    next >
Assembly Source File  |  1987-07-02  |  17KB  |  474 lines

  1. ;----- zansi_f.asm ---------------------------------------------
  2. ; Zephyr ANSI terminal driver.
  3. ;    Copyright (C) 1986-1987, Thomas Hanlin III, Alexandria VA.
  4. ;    Based on original code for NANSI by Daniel Kegel, Pasadena CA.
  5. ;------------------------------------------------------------------------
  6. ; Each routine is called with the following register usage:
  7. ;  AX = max(1, value of first parameter)
  8. ;  Z flag is set if first parameter is zero.
  9. ;  CX = number of paramters
  10. ;  SI = offset of second parameter from CS
  11. ;  DS = CS
  12. ;  ES:DI points to the current location on the memory-mapped screen.
  13. ;  DX is number of characters remaining on the current screen line.
  14. ; The control routine is free to trash AX, BX, CX, SI, and DS.
  15. ; It must preserve ES, and can alter DX and DI if it wants to move the
  16. ; cursor.
  17. ;----------------------------------------------------------------
  18.  
  19.         ; To zansi_p.asm
  20.         public  ansi_fn_table
  21.  
  22.         ; From zansi.asm
  23.         extrn   port_6845:word
  24.         extrn   cur_coords:word, saved_coords:word
  25.         extrn   cur_x:byte, max_x:byte
  26.         extrn   cur_y:byte, max_y:byte
  27.         extrn   cur_attrib:byte, wrap_flag:byte
  28.         extrn   xy_to_regs:near
  29.         extrn   get_blank_attrib:near
  30.         extrn   cpr_esc:byte, cprseq:word
  31.         extrn   video_mode:byte
  32.  
  33. keybuf  struc                           ; used in making cpr sequence
  34. len     dw      ?
  35. adr     dw      ?
  36. keybuf  ends
  37.  
  38.  
  39. ABS40   segment at 40h
  40.         org     1ah
  41. buffer_head     dw      ?       ; Used in 'flush input buffer' dos call.
  42. buffer_tail     dw      ?
  43.  
  44.         org     49h
  45. crt_mode        db      ?
  46. crt_cols        dw      ?
  47. crt_len         dw      ?
  48. crt_start       dw      ?
  49. cursor_posn     dw      8 dup (?)
  50. cursor_mode     dw      ?
  51. active_page     db      ?
  52. addr_6845       dw      ?
  53. crt_mode_set    db      ?
  54. crt_palette     db      ?
  55.  
  56. ABS40   ends
  57.  
  58. code    segment byte public 'CODE'
  59.         assume cs:code, ds:code
  60.  
  61. ;----- byteout ---------------------------------------------------
  62. ; Converts al to a decimal ASCII string (in 0..99),
  63. ; stores it at ES:DI++.  Returns DI pointing at byte after last digit.
  64. ; Destroys DL.
  65.  
  66. byteout proc    near
  67.         aam
  68.         add     ax, 3030h
  69.         xchg    ah, al
  70.         stosb
  71.         xchg    ah, al
  72.         stosb
  73.         ret
  74. byteout endp
  75.  
  76. ;----- ansi_fn_table -----------------------------------
  77. ; Table of offsets of terminal control subroutines in order of
  78. ; the character that invokes them, @..Z, a..z.  Exactly 53 entries.
  79. ; All the subroutines are defined below in this module.
  80. ansi_fn_table   label   word
  81.         dw      ic,  cup, cdn, cfw, cbk         ; @, A, B, C, D
  82.         dw      nul, nul, nul, hvp, nul         ; E, F, G, H, I
  83.         dw      eid, eil, il,  d_l, nul         ; J, K, L, M, N
  84.         dw      nul, dc,  nul, nul, nul         ; O, P, Q, R, S
  85.         dw      nul, nul, nul, nul, nul         ; T, U, V, W, X
  86.         dw      nul, nul                        ; Y, Z
  87.         dw      nul, nul, nul, nul, nul         ; a, b, c, d, e
  88.         dw      hvp, nul, sm,  nul, nul         ; f, g, h, i, j
  89.         dw      nul, rm,  sgr, dsr, nul         ; k, l, m, n, o
  90.         dw      nul, nul, nul, scp, nul         ; p, q, r, s, t
  91.         dw      rcp, nul, nul, nul, nul         ; u, v, w, x, y
  92.         dw      nul                             ; z
  93.  
  94. ansi_functions  proc    near            ; set return type to NEAR
  95.  
  96. ;----- nul ---------------------------------------------
  97. ; No-action ansi sequence; called when unknown command given.
  98. nul:    ret
  99.  
  100. ;----- Cursor Motion -----------------------------------------------
  101.  
  102. ;-- cursor to y,x
  103. hvp:    or      al,al           ; First parameter is desired Y coordinate.
  104.         jz      hvp_yok
  105.         dec     ax              ; Convert to zero-based coordinates.
  106. hvp_yok:mov     cur_y,al
  107.         ; Get second parameter, if it is there, and set X with it.
  108.         xor     ax,ax
  109.         cmp     cx,2            ; was there a second parameter?
  110.         jb      hvp_xok
  111.         lodsb                   ; yes.
  112.         or      al,al
  113.         jz      hvp_xok
  114.         dec     ax              ; convert to zero-based coordinates.
  115. hvp_xok:mov     cur_x,al
  116.  
  117.         ; Clip to maximum coordinates.
  118. hvp_set:
  119.         mov     ax, cur_coords          ; al = x, ah = y
  120.         cmp     al, max_x
  121.         jbe     hvp_sxok
  122.         mov     al, max_x
  123.         mov     cur_x, al
  124. hvp_sxok:
  125.         cmp     ah, max_y
  126.         jbe     hvp_syok
  127.         mov     al, max_y
  128.         mov     cur_y, al
  129. hvp_syok:
  130.         ; Set values of DX and DI accordingly.
  131.         call    xy_to_regs
  132.         ret
  133.  
  134. ;-- cursor forward --
  135. cfw:    add     cur_x, al
  136.         jmp     hvp_set
  137.  
  138. ;-- cursor back -----
  139. cbk:    sub     cur_x, al
  140.         jae     cbk_ok
  141.         mov     cur_x, 0
  142. cbk_ok: jmp     hvp_set
  143.  
  144. ;-- cursor down -----
  145. cdn:    add     cur_y, al
  146.         jmp     hvp_set
  147.  
  148. ;-- cursor up -------
  149. cup:    sub     cur_y, al
  150.         jae     cup_ok
  151.         mov     cur_y, 0
  152. cup_ok: jmp     hvp_set
  153.  
  154. ;-- save cursor position --------------------------------------
  155. scp:    mov     ax, cur_coords
  156.         mov     saved_coords, ax
  157.         ret
  158.  
  159. ;-- restore cursor position -----------------------------------
  160. rcp:    mov     ax, saved_coords
  161.         mov     cur_coords, ax
  162.         jmp     hvp_set         ; Clip in case we have switched video modes.
  163.  
  164. ;-- set graphics rendition ------------------------------------
  165. ; Modifies the color in which new characters are written.
  166.  
  167. sgr:    dec     si              ; get back pointer to first parameter
  168.         or      cx, cx          ; Did he give any parameters?
  169.         jnz     sgr_loop
  170.         mov     [si],cl         ; no parameters, so fake
  171.         inc     cx              ; one with the default value.
  172.  
  173. sgr_loop:                ; Handles each parameter
  174.         lodsb                   ; al = next parameter
  175.         push    cx
  176.         mov     cx,colors
  177.         mov     bx,offset color_table -3
  178. sgr_search:
  179.         add     bx,3
  180.         cmp     al,[bx]
  181.         loopne  sgr_search      ; until match found or done
  182.         jne     sgr_loopx
  183.  
  184.         ; If parameter named a known color, set the current color variable.
  185.         mov     bx,1[bx]
  186.         mov     al,cur_attrib
  187.         and     al,bl
  188.         or      al,bh
  189.         mov     cur_attrib,al
  190. sgr_loopx:
  191.         pop     cx
  192.         loop    sgr_loop                ; until no more parameters.
  193.         ret
  194.  
  195. ;-- erase in line ----------------------------------------
  196. ; Uses BIOS to scroll away a one-line rectangle
  197. eil:    push    dx
  198.         mov     cx, cur_coords
  199.         mov     dh, ch
  200.         jmp     short scrollem
  201.  
  202. ;-- erase in display -------------------------------------
  203. ; Uses BIOS to scroll away all of display
  204. eid:    cmp     al,2
  205.         jnz     eid_ignore      ; param must be two
  206.         xor     cx,cx
  207.         mov     cur_coords,cx
  208.         call    xy_to_regs      ; doesn't modify CX
  209.         push    dx
  210.         mov     dh,max_y
  211. scrollem:
  212.         call    get_blank_attrib
  213.         mov     bh,ah
  214.         mov     dl,max_x
  215.         mov     ax,600h
  216.         int     10h
  217.         pop     dx
  218. eid_ignore:
  219.         ret
  220.  
  221. ;-- device status report --------------------------------
  222. ; Stuffs an escape, a left bracket, current Y, semicolon, current X,
  223. ; a capital R, and a carriage return into input stream.
  224. ; The coordinates are 1 to 3 decimal digits each.
  225.  
  226. dsr:    push    di
  227.         push    dx
  228.         push    es
  229.         mov     ax,cs
  230.         mov     es,ax
  231.         std                     ; Store string in reversed order for fun
  232.         mov     di,offset cpr_esc - 2
  233.         mov     al,cur_y
  234.         inc     al              ; convert to one-based coords
  235.         call    byteout         ; row
  236.         mov     al,';'
  237.         stosb
  238.         mov     al,cur_x
  239.         inc     al              ; convert to one-based coords
  240.         call    byteout         ; column
  241.         mov     al,'R'          ; R ANSI function 'Cursor Position Report'
  242.         stosb
  243.         mov     al,13
  244.         mov     word ptr cprseq.adr, di ; save pointer to last char in string
  245.         stosb                           ; send a carriage return, too
  246.         mov     ax,offset cpr_esc
  247.         sub     ax,di                   ; ax is # of characters in string
  248.         mov     word ptr cprseq.len,ax  ; pass info to the getchar routine
  249.         cld
  250.         pop     es
  251.         pop     dx
  252.         pop     di
  253.         ret
  254.  
  255. ;---- Delete/Insert Lines -------------------------------
  256. ; AL is number of lines to delete/insert.
  257. ; Preserves DX, DI; does not move cursor.
  258.  
  259. d_l:    ; Delete lines.
  260.         mov     ah, 6                   ; BIOS: scroll up
  261.         jmp     short il_open
  262.  
  263. il:     ; Insert lines.
  264.         mov     ah, 7                   ; BIOS: scroll down
  265.  
  266. il_open:
  267.         ; Whether inserting or deleting, limit him to (max_y - cur_y) lines;
  268.         ; if above that, we're just clearing; set AL=0 so BIOS doesn't burp.
  269.         mov     bh, max_y
  270.         sub     bh, cur_y
  271.         cmp     al, bh
  272.         jbe     il_ok                   ; DRK 9/4...
  273.         xor     al,al           ; he tried to move too far
  274. il_ok:
  275.         push    ax
  276.         call    get_blank_attrib
  277.         mov     bh, ah                  ; color to use on new blank areas
  278.         pop     ax                      ; AL is number of lines to scroll.
  279.  
  280.         xor     cl,cl                   ; upper-left-x of data to scroll
  281.         mov     ch, cur_y               ; upper-left-y of data to scroll
  282.         push    dx
  283.         mov     dl, max_x               ; lower-right-x
  284.         mov     dh, max_y               ; lower-right-y (zero based)
  285.         int     10h                     ; call BIOS to scroll a rectangle.
  286.         pop     dx
  287.         ret                             ; done.
  288.  
  289. ;-- Insert / Delete Characters ----------------------------
  290. ; AL is number of characters to insert or delete.
  291. ; Preserves DX, DI; does not move cursor.
  292.  
  293. ic:     mov     ch, 1                   ; 1 => swap dest & source below
  294.         jmp     short dc_ch
  295.  
  296. dc:     xor     cl,cl
  297.  
  298. dc_ch:
  299.         cmp     cs:video_mode, 4
  300.         jb      DC_CH_DO
  301.         cmp     cs:video_mode, 7
  302.         jnz     dc_ret                  ; | if in graphics mode, ignore.
  303. DC_CH_DO:
  304.         ; AL = number of chars to ins or del (guarenteed nonzero).
  305.         ; Limit him to # of chars left on line.
  306.         cmp     al, dl
  307.         jbe     dc_cok
  308.         mov     al, dl
  309. dc_cok:
  310.         push    di                      ; DI is current address of cursor
  311.         xchg    ax, cx                  ; CX gets # of chars to ins/del
  312.         mov     bp, cx                  ; BP gets # of columns to clear.
  313.  
  314.         ; Set up source = destination + cx*2, count = dx - cx
  315.         xor     ch,ch                   ; make it a word
  316.         mov     si, di
  317.         add     si, cx
  318.         add     si, cx
  319.         neg     cl
  320.         add     cl, dl
  321.         xor     ch,ch                   ; CX = # of words to transfer
  322.         cld                             ; REP increments si & di
  323.  
  324.         ; If this is an insert, then flip transfer around in both ways.
  325.         test    ah, 1
  326.         jz      dc_noswap
  327.         xchg    di,si           ; source <-> dest
  328.         std                     ; up <-> down
  329.         mov     ax,cx           ; make move over same range
  330.         dec     ax
  331.         shl     ax,1            ; AX=dist from 1st to last byte.
  332.         add     di,ax           ; Start transfer at high end of block
  333.         add     si,ax           ;  instead of low end.
  334. dc_noswap:
  335.         ; Move those characters.
  336.         push    es
  337.         pop     ds
  338.         rep     movsw
  339.         mov     cx,bp
  340.         ; Figure out what color to make the new blanks.
  341.         call    get_blank_attrib
  342.         mov     al,' '
  343.         ; Blank out vacated region.
  344.         rep     stosw
  345.  
  346.         ; All done.
  347.         cld                             ; restore normal REP state and
  348.         pop     di                      ;  cursor address.
  349. dc_ret: ret
  350.  
  351.  
  352. ;---- set / reset mode ---------------------------------------
  353. ; Sets graphics/text mode; also sets/resets "no wrap at eol" mode.
  354. sm:     mov     cl, 0ffh        ; set
  355. sm_rs:
  356.         ; Is it "wrap at eol" ?
  357.         cmp     al,7
  358.         jnz     sm_notwrap
  359.         mov     wrap_flag, cl   ; true = wrap at EOL
  360.         ret
  361. sm_notwrap:
  362.         ; Is it "set highest number of screen lines available"?
  363.         cmp     al, 43
  364.         jnz     sm_video
  365.         ; Only valid for the Enhanced Graphics Adaptor on
  366.         ; a monochrome display or an enhanced color display.
  367.         ; Test presence of EGA by calling BIOS fn 12h.10h.
  368.         mov     ah, 12h
  369.         mov     bx, 0ff10h
  370.         int     10h                     ; bh=0-1, bl=0-3 if EGA
  371.         test    bx, 0FEFCH
  372.         jnz     sm_done                 ; sorry, charlie
  373.         ; 43 line mode only allowed in text modes, for now.
  374.         cmp     cs:video_mode, 4
  375.         jb      DO_43L
  376.         cmp     cs:video_mode, 7
  377.         jnz     sm_done
  378.  
  379. DO_43L:
  380.         xor     ah,ah                   ; "Set video mode"
  381.         mov     al, video_mode          ; Re-init current mode
  382.         int     10h
  383.  
  384.         mov     ax,1112h                ; Load 8x8 font
  385.         xor     bl,bl                   ; (instead of 8x14)
  386.         int     10h
  387.  
  388.         mov     ax, 1200h               ; Load new printscreen
  389.         mov     bl,20h
  390.         int     10h
  391.  
  392.         mov     ah,1
  393.         mov     cx,0707h                ; (Load cursor scan lines)
  394.         int     10h
  395.         ; | Patch; this gotten by painful observation of
  396.         ; | IBM's professional editor.  I think there's a
  397.         ; | documented bug in Video Bios's "load cursor scan line"
  398.         ; | call; try looking in latter 1985 PC Tech Journal.
  399.         mov     dx, port_6845           ; '6845' command reg
  400.         mov     al, 10
  401.         out     dx, al
  402.         inc     dx
  403.         mov     al, 7
  404.         out     dx, al                  ; set cursor start line
  405.         ; Assume that gets us 43 lines.
  406.         mov     max_y, 42
  407.         jmp     short sm_home
  408. sm_video:
  409.         ; It must be a video mode.  Call BIOS.
  410.         xor     ah,ah           ; "set video mode"
  411.         int     10h
  412.         ; Assume that gets us 25 lines.
  413.         mov     max_y,24
  414. sm_home:
  415.         ; Read the BIOS buffer address/cursor position variables.
  416.         mov     ax,abs40
  417.         push    ds
  418.         mov     ds,ax
  419.         assume  ds:abs40
  420.         ; Find current video mode and screen size.
  421.         mov     ax,word ptr crt_mode    ; al = crt mode; ah = # of columns
  422.         pop     ds
  423.         mov     video_mode,al
  424.         dec     ah                      ; ah = max column
  425.         mov     max_x,ah
  426.  
  427.         ; Since cursor may end up in illegal position, it's best to
  428.         ; just go home after switching video modes.
  429.         mov     cur_coords,0
  430.         call    xy_to_regs
  431. sm_done:
  432.         ret
  433.  
  434. rm:     xor     cl,cl           ; reset
  435.         jmp     sm_rs
  436.  
  437.  
  438. ansi_functions  endp    ; end dummy procedure block
  439.  
  440.  
  441.  
  442. ;-------- Color table -----------------------------------------
  443. ; Used in "set graphics rendition"
  444. colors  equ     22                      ; number of colors in table
  445. color_table:
  446.         db      0, 000h,07h             ; all attribs off; normal.
  447.         db      1, 0ffh,08h             ; bold
  448.         db      4, 0f8h,01h             ; underline
  449.         db      5, 0ffh,80h             ; blink
  450.         db      7, 0f8h,70h             ; reverse
  451.         db      8, 088h,00h             ; invisible
  452.  
  453.         db      30,0f8h,00h             ; black foreground
  454.         db      31,0f8h,04h             ; red
  455.         db      32,0f8h,02h             ; green
  456.         db      33,0f8h,06h             ; yellow
  457.         db      34,0f8h,01h             ; blue
  458.         db      35,0f8h,05h             ; magenta
  459.         db      36,0f8h,03h             ; cyan
  460.         db      37,0f8h,07h             ; white
  461.  
  462.         db      40,08fh,00h             ; black background
  463.         db      41,08fh,40h             ; red
  464.         db      42,08fh,20h             ; green
  465.         db      43,08fh,60h             ; yellow
  466.         db      44,08fh,10h             ; blue
  467.         db      45,08fh,50h             ; magenta
  468.         db      46,08fh,30h             ; cyan
  469.         db      47,08fh,70h             ; white
  470.  
  471.  
  472. code    ends
  473.         end
  474.